<?php

class NoBusinessBase_File_Transfer_Adapter_Http extends Zend_File_Transfer_Adapter_Http
{
   protected $_finalUploadPath;
   protected $_reservedFileNames = array();

   protected $mDirectoryPermissions;
   protected $mFilePermissions;
   protected $mDirectoryOwner;
   protected $mFileOwner;

   public function __construct($uploadPath, $overrideFileNames = true, $directoryPermissions = 0755, $filePermissions = 0664, $directoryOwner = null, $fileOwner = null)
   {
      parent::__construct();
      
      $this->mDirectoryPermissions = $directoryPermissions;
      $this->mFilePermissions = $filePermissions;
      $this->mDirectoryOwner = $directoryOwner;
      $this->mFileOwner = $fileOwner;
      
      $this->setOptions(array(
         'ignoreNoFile'    => true
      ));

      $this->_finalUploadPath = realpath($uploadPath);
      $this->setDestination($this->_finalUploadPath);
      
      if($overrideFileNames)
      {
         foreach($this->_files as &$file)
            $this->setUniqueFileName($file['name']);
      }
   }

   public function receive($files = null)
   {
      if(!parent::receive($files))
         return false;
      
      $files = $this->getFileInfo();
      foreach($files as $file)
      {
         $pathInfo = pathinfo($file['tmp_name']);
         
         @chmod($pathInfo['dirname'], $this->mDirectoryPermissions);
         if($this->mDirectoryOwner !== null)
            @chown($pathInfo['dirname'], $this->mDirectoryOwner);
         
         @chmod($file['tmp_name'], $this->mFilePermissions);
         if($this->mDirectoryOwner !== null)
            @chown($pathInfo['tmp_name'], $this->mFileOwner);
      }
      
      return true;
   }

   public function setDestination($destination, $files = null)
   {
      parent::setDestination($destination, $files);
      
      $orig = $files;
      $destination = rtrim($destination, "/\\");

      if ($files === null)
      {
         foreach ($this->_files as $file => $content)
         {
            $manifestDestination = rtrim($file, "/\\");
            $fullDestination = rtrim($destination, "/\\") . '/' . $manifestDestination;
            $pos = strrpos($fullDestination, "/");
            if($pos !== false)
               $fullDestination = substr($fullDestination, 0, $pos);
            @mkdir($fullDestination, $this->mDirectoryPermissions, true);
            
            $leafDirs = rtrim($fullDestination, "/\\");
            while($leafDirs != $destination)
            {
               chmod($leafDirs, $this->mDirectoryPermissions);
               $leafDirs = dirname($leafDirs);
            }
            
            $this->_files[$file]['destination'] = $fullDestination;
         }
      }
      
      return $this;
   }

   protected function &setUniqueFileName(&$file)
   {
      $extPos = strrpos($file, '.');
      $ext = '';
      if($extPos !== false)
      {
         $ext  = substr($file, $extPos);
         $file = substr($file, 0, $extPos);
      }

      $file = md5($file . time()) . $ext;
      while(!$this->isUniqueFileName($file))
         $file = md5($file . time() + rand(0, 9000)) . $ext;
      $this->_reservedFileNames[] = $file;
   }

   protected function isUniqueFileName($testName)
   {
      $result = true;
      if(in_array($testName, $this->_reservedFileNames))
         return false;

      if($handle = opendir($this->_finalUploadPath))
      {
         while (false !== ($file = readdir($handle)))
         {
            if($file == $testName)
            {
               $result = false;
               break;
            }
         }
      }
      closedir($handle);
      return $result;
   }
}

